(* ` *)

type ide = string;;
type loc = int;;
exception AddressOutOfBounds of loc;;
exception UnboundIde of ide;;

type vtype = 
		   Int of int
		| Bool of int;;

type dtype = DInt | DBool ;;
type ctype = TRef | TValue;;

type func = CBV of ide*exp | CBR of ide*ide 
and
(*Tipi di espressione*)
exp =
    N of int
	| B of int
	| Fun of func
	| Val of ide
  | ArrayVal of ide * exp
  | EAdd of exp * exp
  | ESub of exp * exp
  | EMul of exp * exp
	| EMax of exp * exp
  | Eq of exp * exp
  | Lt of exp * exp
  | Not of exp
  | And of exp * exp
	 | Or of exp * exp
;;
type com =
    Skip
  | AssignVar of ide * exp
  | AssignArray of ide * exp * exp
	| Exchange of ide * exp * exp
  | Cseq of com * com
  | If of exp * com * com
  | While of exp * com
;;
type return = Return of exp;;

(*type func = Func of  dtype*dtype*ide * dec * prog
and *)
type prog = Program of dec * block
and
block = 
	| BlockSeq of block*block
	| DecBlock of dec*block
	| Com of com
and
 dec =
    Empty
  | Const of dtype*ide * vtype
  | Var of dtype*ide
	| Init of dtype*ide * exp
  | Array of dtype*ide * int
	| Function of  dtype*ide*ctype*dtype*ide * prog*return
  | Dseq of dec * dec
;;
(* Tipi per Commands*)
 
type dval =
    Unbound
  | DConst of dtype*vtype
  | DVar of dtype*loc
  | DArray of dtype*int*loc
	| DFunc of ctype*dtype*dtype*ide * prog*return
	| DPointer of dtype * loc
;;

type env = Env of (ide -> dval);;

(* Environment *)
let emptyenv = fun () -> Env (fun x -> Unbound);;
let bind (Env rho) x d = Env (fun y -> if y=x then d else rho y);;
let applyenv (Env rho) x = match rho x with   
  | _ as d -> d
;;
